package com.xhga.server;

import com.xhga.common.ProtostuffUtil;
import com.xhga.common.RpcRequest;
import com.xhga.common.RpcResponse;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;

/**
 * Created by Hua wb on 2018/11/29.
 */
public class RpcHandler extends ChannelInboundHandlerAdapter {

    private Map<String, Object> annotationMap;

    public RpcHandler(Map<String, Object> annotationMap) {
        this.annotationMap = annotationMap;
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("请求消息：" + msg);
        if (msg instanceof RpcRequest) {
            RpcRequest rpcRequest = (RpcRequest) msg;
            RpcResponse rpcResponse = handler(rpcRequest);
            System.out.println("返回消息：" + rpcResponse);
            ctx.writeAndFlush(rpcResponse).addListener(ChannelFutureListener.CLOSE);
        }
    }

    private RpcResponse handler(RpcRequest rpcRequest) {
        String requestId = rpcRequest.getRequestId();
        String className = rpcRequest.getClassName();
        String methodName = rpcRequest.getMethodName();
        Class<?>[] parameterTypes = rpcRequest.getParameterTypes();
        Object[] parameters = rpcRequest.getParameters();
        RpcResponse rpcResponse = new RpcResponse();
        try {
            Class<?> aClass = Class.forName(className);
            Method method = aClass.getMethod(methodName, parameterTypes);
            Object result = method.invoke(annotationMap.get(className), parameters);
            rpcResponse.setRequestId(requestId);
            rpcResponse.setResult(result);
            rpcResponse.setSuccess(true);
        } catch (Exception e) {
            rpcResponse.setSuccess(false);
            System.out.println("server handler:error.");
            e.printStackTrace();
        }
        return rpcResponse;
    }
}
